﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using WisPortal.Models;
using System.IO;
using System.Xml;
using System.Text;
using System.Data;
using WisPortal.Data;
using WisPortal;

namespace WisPortal.Areas.Train.Controllers
{
    /// <summary>
    /// 故障诊断控制器
    /// </summary>
    public class ErrorController : BaseController
    {
        private XmlDocument doc;
        private DataMapping dm;
        private const string CATEGORIES = "Categories";
        private const string CATEGORY = "Category";
        private const string ERRORS = "Errors";
        private const string ERROR = "Error";
        private const string CONTENT = "Content";
        private const string SYMPTOMS = "Symptoms";
        private const string SYMPTOM = "Symptom";

        public ErrorController()
        {
            doc = new XmlDocument();
            dm = new DataMapping(HttpContext);
        }

        /// <summary>
        /// 1.15 故障列表
        /// </summary>
        /// <param name="traintype"></param>
        /// <returns></returns>
        public ActionResult GetErrors(string traintype)
        {
            XmlNode categoriesNode = doc.CreateElement(CATEGORIES);
            doc.AppendChild(categoriesNode);
            DataSet dsCategories = GetErrorCategories(traintype);
            if (DB.HasData(dsCategories))
            {
                foreach (DataRow categoryRow in dsCategories.Tables[0].Rows)
                {
                    XmlNode categoryNode = CreateCategoryByRow(categoryRow);
                    if (categoryNode != null)
                        categoriesNode.AppendChild(categoryNode);
                }
            }
            return Content(JsonConvert.SerializeXmlNode(doc, Newtonsoft.Json.Formatting.Indented).Replace("\"@", "\""));
        }

        /// <summary>
        /// 1.17
        /// </summary>
        /// <param name="trainCode"></param>
        /// <returns></returns>
        public ActionResult GetTrainTypeXml(string trainCode)
        {
            string sql = string.Format("SELECT [CONTENT] FROM [TSX].[dbo].[TSX_TRAINTYPE] WHERE CODE = '{0}'", trainCode);
            DataSet dsContent = DB.GetDataSet(sql);
            if (DB.HasData(dsContent))
            {
                string content = dsContent.Tables[0].Rows[0]["CONTENT"].ToString();
                Stream s = new MemoryStream(System.Text.UTF8Encoding.Default.GetBytes(content));
                return File(s, "application/octet-stream", string.Format("type_{0}.xml", trainCode));
                //return Content(content);
            }
            else
                return GetResult(CODE_ERROR_NODATAFOUND, "未找到XML数据");
        }

        /// <summary>
        /// 1.16 GetErrorList
        /// </summary>
        /// <param name="errorId"></param>
        /// <returns></returns>
        public ActionResult GetErrorXml(string errorId)
        {
            string sql = string.Format("SELECT [CONTENT] FROM [TSX].[dbo].[TSX_ERROR_ERROR] WHERE ID = '{0}'", errorId);
            DataSet dsContent = DB.GetDataSet(sql);
            if (DB.HasData(dsContent))
            {
                string content = dsContent.Tables[0].Rows[0]["CONTENT"].ToString();
                Stream s = new MemoryStream(System.Text.UnicodeEncoding.UTF8.GetBytes(content));
                s.Seek(2, 0);
                return File(s, "application/octet-stream",string.Format("error_{0}.xml",errorId));
                //return Content(content);
            }
            else
                return GetResult(CODE_ERROR_NODATAFOUND,"未找到XML数据");
        }

        private DataSet GetErrorCategories(string traintype)
        {
            string sql = string.Format("SELECT TSX_TRAINTYPE.CODE, TSX_ERROR_CATEGORY.Id, TSX_ERROR_CATEGORY.POSITION," +
                "TSX_ERROR_CATEGORY.NAME, TSX_ERROR_CATEGORY.DESCRIPTION,TSX_ERROR_CATEGORY.TRAINTYPEID,TSX_ERROR_CATEGORY.MODIFIEDTIME FROM TSX_ERROR_CATEGORY " +
                " INNER JOIN TSX_TRAINTYPE ON TSX_ERROR_CATEGORY.TRAINTYPEID = TSX_TRAINTYPE.ID "+
                "WHERE   (TSX_TRAINTYPE.CODE = N'{0}') ORDER BY TSX_ERROR_CATEGORY.POSITION", traintype);
            return DB.GetDataSet(sql);
        }

        private XmlNode CreateCategoryByRow(DataRow row)
        {
            XmlNode node = doc.CreateElement(CATEGORY);

            dm.AddAttributeToNode(doc, node, "id", row["Id"].ToString());
            dm.AddAttributeToNode(doc, node, "name", row["NAME"].ToString());
            dm.AddAttributeToNode(doc, node, "position", row["POSITION"].ToString());
            dm.AddAttributeToNode(doc, node, "description", row["DESCRIPTION"].ToString());
            dm.AddAttributeToNode(doc, node, "modifiedtime", row["MODIFIEDTIME"].ToString());


            XmlNode errorsNode = CreateErrors(row["Id"].ToString());
            node.AppendChild(errorsNode);

            return node;
        }

        private XmlNode CreateErrors(string categoryId)
        {
            XmlNode errorsNode = doc.CreateElement(ERRORS);
            //Get Errors
            string sql = string.Format("SELECT TSX_ERROR_ERROR.ID,TSX_ERROR_ERROR.NAME,TSX_ERROR_ERROR.POSITION,TSX_ERROR_ERROR.CODE,TSX_ERROR_ERROR.DESCRIPTION,TSX_ERROR_ERROR.MODIFIEDTIME FROM TSX_ERROR_ERROR WHERE (CATEGORYID = '{0}') ORDER BY POSITION",
                categoryId);
            DataSet dsErrors = DB.GetDataSet(sql);
            if (DB.HasData(dsErrors))
            {
                foreach (DataRow row in dsErrors.Tables[0].Rows)
                {
                    XmlNode errorNode = doc.CreateElement(ERROR);

                    dm.AddAttributeToNode(doc, errorNode, "id", row["ID"].ToString());
                    dm.AddAttributeToNode(doc, errorNode, "name", row["NAME"].ToString());
                    dm.AddAttributeToNode(doc, errorNode, "position", row["POSITION"].ToString());
                    dm.AddAttributeToNode(doc, errorNode, "code", row["CODE"].ToString());
                    dm.AddAttributeToNode(doc, errorNode, "description", row["DESCRIPTION"].ToString());
                    dm.AddAttributeToNode(doc, errorNode, "modifiedtime", row["MODIFIEDTIME"].ToString());

                    //dm.AddAttributeToNode(doc, errorNode, "content", row["DESCRIPTION"].ToString());

                    //Content node
                    //XmlNode contentNode = doc.CreateElement(CONTENT);
                    //XmlCDataSection cData = doc.CreateCDataSection(row["CONTENT"].ToString());
                    //contentNode.AppendChild(cData);
                    //errorNode.AppendChild(contentNode);

                    //Symptoms
                    XmlNode symptoms = CreateSymptoms(row["ID"].ToString());                    
                    errorNode.AppendChild(symptoms);

                    errorsNode.AppendChild(errorNode);
                }
            }
            return errorsNode;
        }

        private XmlNode CreateSymptoms(string errorId)
        {
            XmlNode symptoms = doc.CreateElement(SYMPTOMS);
            string sql = string.Format("SELECT TSX_ERROR_ERRORSYMPTOM.* FROM TSX_ERROR_ERRORSYMPTOM WHERE (ERRORID = '{0}') ORDER BY POSITION",
                errorId);
            DataSet dsSymptoms = DB.GetDataSet(sql);
            if (DB.HasData(dsSymptoms))
            {
                foreach (DataRow row in dsSymptoms.Tables[0].Rows)
                {
                    XmlNode symptomNode = doc.CreateElement(SYMPTOM);

                    dm.AddAttributeToNode(doc, symptomNode, "id", row["ID"].ToString());
                    dm.AddAttributeToNode(doc, symptomNode, "name", row["NAME"].ToString());
                    dm.AddAttributeToNode(doc, symptomNode, "description", row["DESCRIPTION"].ToString());
                    dm.AddAttributeToNode(doc, symptomNode, "position", row["POSITION"].ToString());
                    dm.AddAttributeToNode(doc, symptomNode, "modifiedtime", row["MODIFIEDTIME"].ToString());


                    symptoms.AppendChild(symptomNode);
                }
            }
            return symptoms;
        }
    }
}
